package com.bigdata.service.impl;

import com.bigdata.dao.AppMapper;
import com.bigdata.entity.pojo.*;
import com.bigdata.entity.vo.AppFlowTrackingVO;
import com.bigdata.entity.vo.AppMapVO;
import com.bigdata.entity.vo.AppTopVO;
import com.bigdata.entity.vo.LandMarkAppTopVO;
import com.bigdata.service.AppService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigInteger;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class AppServiceImpl implements AppService {
    @Autowired
    private AppMapper appMapper;
    @Override
    public List<AppTopVO>getAppTop(Long amount){
        List<AppTopVO> list = appMapper.getAppTop(amount);
        return list;
    }
    @Override
    public AppFlowTrackingVO AppFlowTracking(){
        Long amount=5L;
        List<AppTopVO>appTopVOList=appMapper.getAppTop(amount);
        AppFlowTrackingVO appFlowTrackingVO=new AppFlowTrackingVO();
        List<String>appName=appTopVOList.stream().map(AppTopVO::getAppName).collect(Collectors.toList());
        List<List<BigInteger>>traffic=new ArrayList<>();
        List<String>time=new ArrayList<>();
        for( Integer i=2010;i<=2021;i++){
            time.add(i.toString());
        }
        LocalDateTime start = LocalDateTime.parse("2010-01-01T00:00:00");
        LocalDateTime end = LocalDateTime.parse("2021-12-31T23:59:59");
        // 定义格式化器
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHH");

        // 格式化 LocalDateTime 为字符串
        String startString = start.format(formatter);
        String endString =end.format(formatter);
        Map<String,Map<String,BigInteger> >map=new HashMap<>();
        List<AppTraffic>data=appMapper.AppFlowTracking(appName,startString,endString);
        for(AppTraffic appTraffic:data){
            Map<String,BigInteger> temp=map.getOrDefault(appTraffic.getAppName(),new HashMap<>());
            temp.put(appTraffic.getYear(),appTraffic.getHeat());
            map.put(appTraffic.getAppName(),temp);
        }

        for(String name:appName){
            List<BigInteger>heat=new ArrayList<>();
            Map <String,BigInteger>temp=map.get(name);
            for(String year:time){
                if(temp.containsKey(year)){
                    heat.add(temp.get(year));
                }
                else{
                    heat.add(BigInteger.ZERO);
                }
            }
            traffic.add(heat);
        }
        appFlowTrackingVO.setSeriesData(traffic);
        appFlowTrackingVO.setLegends(appName);
        appFlowTrackingVO.setXAxisData(time);
        return appFlowTrackingVO;
    }
    public List<AppMapVO>getAppMap(){
        List<AppMapVO> list=appMapper.getMap();
        return list;
    }
    public LandMarkAppTopVO getAppTrafficOfNetType(){
        Long amount=6L;
        List<AppTopVO>appTopVOList=appMapper.getAppTop(amount);
        List<String>appNames=appTopVOList.stream().map(AppTopVO::getAppName).collect(Collectors.toList());
        List<AppTrafficOfNetType>appTrafficOfNetType=appMapper.getTrafficOfNetType(appNames);
        Map<String,Map<String,BigInteger>>map=new HashMap<>();
        for(AppTrafficOfNetType appTrafficOfNetType1:appTrafficOfNetType){
            Map<String,BigInteger>temp=map.getOrDefault(appTrafficOfNetType1.getName(),new HashMap<>());
            temp.put(appTrafficOfNetType1.getType(),appTrafficOfNetType1.getHeat());
            map.put(appTrafficOfNetType1.getName(),temp);
        }
        List<BigInteger>g4=new ArrayList<>();
        List<BigInteger>g3=new ArrayList<>();
        List<BigInteger>g2=new ArrayList<>();
        List<BigInteger>all=new ArrayList<>();
        for(String name:appNames){
            Map<String,BigInteger>temp=map.get(name);
            BigInteger heatOfg2=temp.getOrDefault("2G",BigInteger.ZERO);
            BigInteger heatOfg3=temp.getOrDefault("3G",BigInteger.ZERO);
            BigInteger heatOfg4=temp.getOrDefault("4G",BigInteger.ZERO);
            BigInteger heatOfAll=heatOfg2.add(heatOfg3).add(heatOfg4);
            g4.add(heatOfg4);
            g3.add(heatOfg3);
            g2.add(heatOfg2);
            all.add(heatOfg2);
        }
        NetworkData networkData=new NetworkData();
        networkData.setAll(all);
        networkData.setG4(g4);
        networkData.setG3(g3);
        networkData.setG2(g2);
        LandMarkAppTopVO landMarkAppTopVO=new LandMarkAppTopVO();
        landMarkAppTopVO.setAppNames(appNames);
        landMarkAppTopVO.setNetworkData(networkData);
        return landMarkAppTopVO;
    }

    // 17
    @Override
    public Object getAppTrafficDistribution() {
        // 获取原始数据列表
        List<AppTrafficDistribution> distributions = appMapper.getAppTrafficDistribution();

        // 将原始数据转换为目标格式
        return convertToTargetFormat(distributions);
    }
    // 将原始数据转换为目标格式
    public Map<String, List<Map<String, Object>>> convertToTargetFormat(List<AppTrafficDistribution> distributions) {
        Map<String, List<Map<String, Object>>> resultMap = new HashMap<>();

        // 遍历原始数据列表
        for (AppTrafficDistribution distribution : distributions) {
            // 创建坐标和流量值映射
            Map<String, Object> coordData = new HashMap<>();
            coordData.put("coord", Arrays.asList(Double.parseDouble(distribution.getUserLon()), Double.parseDouble(distribution.getUserLat())));
            coordData.put("value", distribution.getHeat().intValue());

            // 按应用名称分组
            String appName = distribution.getAppName();
            if (!resultMap.containsKey(appName)) {
                resultMap.put(appName, new ArrayList<>());
            }
            resultMap.get(appName).add(coordData);
        }

        return resultMap;
    }

    @Override
    public Object getAppTrafficRankingRank() {
        // 获取原始数据列表
        List<AppTrafficRankingRank> distributions = appMapper.getAppTrafficRankingRank();

        // 处理数据
        Map<String, List<Double>> trafficByType = new HashMap<>();
        Set<String> appNames = new LinkedHashSet<>();

        // 初始化网络类型映射
        trafficByType.put("ALL", new ArrayList<>());
        trafficByType.put("WIFI", new ArrayList<>());
        trafficByType.put("MOBILE", new ArrayList<>());

        // 按应用名称分组数据
        Map<String, Map<String, Double>> appTraffic = new HashMap<>();

        for (AppTrafficRankingRank dist : distributions) {
            appNames.add(dist.getAppName());
            appTraffic.computeIfAbsent(dist.getAppName(), k -> new HashMap<>())
                    .put(dist.getNetworkType(), dist.getTotalTraffic());
        }

        // 只取前5个应用
        List<String> top5Apps = appNames.stream().limit(5).collect(Collectors.toList());

        // 构建返回数据
        Map<String, Object> result = new HashMap<>();
        result.put("legends", Arrays.asList("ALL", "WIFI", "MOBILE"));
        result.put("xAxisData", top5Apps);

        List<List<Double>> seriesData = new ArrayList<>();
        for (String type : Arrays.asList("ALL", "WIFI", "MOBILE")) {
            List<Double> typeData = new ArrayList<>();
            for (String app : top5Apps) {
                Map<String, Double> appData = appTraffic.get(app);
                if ("ALL".equals(type)) {
                    double total = appData.values().stream().mapToDouble(Double::doubleValue).sum();
                    typeData.add(total);
                } else {
                    typeData.add(appData.getOrDefault(type, 0.0));
                }
            }
            seriesData.add(typeData);
        }
        result.put("seriesData", seriesData);

        return result;
    }

    @Override
    public Object getAppTrafficRankingPie() {
        // 获取原始数据列表
        List<AppTrafficRankingPie> distributions = appMapper.getAppTrafficRankingPie();

        // 处理数据
        List<String> names = new ArrayList<>();
        List<Double> values = new ArrayList<>();
        List<String> colors = Arrays.asList("#FF7F50", "#87CEEB", "#DDA0DD", "#90EE90", "#FFB6C1");

        for (AppTrafficRankingPie dist : distributions) {
            names.add(dist.getAppName());
            values.add(dist.getTotalTraffic());
        }

        // 构建返回数据
        Map<String, Object> result = new HashMap<>();
        result.put("names", names);
        result.put("values", values);
        result.put("colors", colors);

        return result;
    }
}
